//
//  EGMBleOperation.h
//  BleSports
//
//  Created by hh on 14-10-24.
//  Copyright (c) 2014年 egoman. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "EGMBleManager.h"
#import "SDKBleManager.h"

@class EGMOnMassDataListener;

#define DEF_MASS_CMD_TIMEOUT_SECOND 60
#define DEF_READ_MASS_CMD_TIMEOUT_SECOND 5
//#define ONE_PACKET_TIMEOUT_SECOND_10 0.05
//#define ONE_PACKET_TIMEOUT_SECOND_100 0.03
//#define ONE_PACKET_TIMEOUT_SECOND_1000 0.015
//#define ONE_PACKET_TIMEOUT_SECOND_5000 0.012
//#define ONE_PACKET_TIMEOUT_SECOND_ELSE 0.01

#define ONE_PACKET_TIMEOUT_SECOND_10 0.05
#define ONE_PACKET_TIMEOUT_SECOND_100 0.04
#define ONE_PACKET_TIMEOUT_SECOND_1000 0.02
#define ONE_PACKET_TIMEOUT_SECOND_5000 0.015
#define ONE_PACKET_TIMEOUT_SECOND_ELSE 0.012
//-----------------------------------------------------------
#pragma mark - EGMBleOperation
//-----------------------------------------------------------
@interface EGMBleOperation : NSObject
@property(strong,nonatomic) EGMBleManager *bleManager;

-(instancetype)initWithBleManager:(EGMBleManager*)bleManager;
-(void)writeCmd:(NSData*)cmd;
-(void)writeCmdOfReadMassData:(NSData*)cmd massDataListener:(EGMOnMassDataListener*)massDataListener;
-(void)writeCmdOfReadMassDataInQueue:(NSData*)cmd massDataListener:(EGMOnMassDataListener*)massDataListener;
-(void)writeCmdOfReadMassDataInTransaction:(NSData*)cmd massDataListener:(EGMOnMassDataListener*)massDataListener;
@end


//-----------------------------------------------------------
#pragma mark - EGMMassDataCmd
//-----------------------------------------------------------
@interface EGMMassDataCmd : NSObject
@property(nonatomic,assign) BOOL isInQueue;
@property(nonatomic,assign) BOOL isInTransaction;
@property(nonatomic,assign) BOOL isTimeout;
@property(nonatomic,assign) NSInteger timeoutSecond;
-(instancetype)initWithTimeoutSecond:(NSInteger)second;
-(void)execute;
-(void) addIntoQueue;
-(void) addIntoTransaction;
-(Class)listenerClass;
+(void) cleanUp;
+(void) beginTransaction;
+(void) endTransaction:(void(^)()) callback;
+(void) queuedCmdExecuteSucceed;
+(NSInteger)generateCmdId;
-(void)retryMassDataCmd;
+(void)addTimeoutCallback:(float)timeoutSecond;
+(void)cancelTimeoutCallback;
@end




//-----------------------------------------------------------
#pragma mark - EGMReadMassDataCmd
//-----------------------------------------------------------
@interface EGMReadMassDataCmd : EGMMassDataCmd<NSCopying>
@property(nonatomic,strong) NSData *cmd;
@property(nonatomic,strong) EGMBleOperation *bleOperation;
@property(nonatomic,strong) EGMOnMassDataListener *massDataListener;
@property(nonatomic,assign) NSInteger execCount;
@property(nonatomic,assign) NSInteger failedRetryCount ;

-(instancetype)initWithCmd:(NSData*)cmd bleOperation:(EGMBleOperation*)bleOperation massDataListener:(EGMOnMassDataListener*)massDataListener;
-(instancetype)initWithCmd:(NSData*)cmd timeoutSecond:(NSInteger)second bleOperation:(EGMBleOperation*)bleOperation massDataListener:(EGMOnMassDataListener*)massDataListener;
@end


//-----------------------------------------------------------
#pragma mark - EGMOnMassDataListener
//-----------------------------------------------------------
@interface EGMOnMassDataListener : NSObject
@property(nonatomic,strong) NSMutableDictionary *allPacketsMap;
@property(nonatomic,assign) NSInteger receivedPacketsCount;
//@property(nonatomic,assign) BOOL isInMassDataQueue;
@property(nonatomic,assign) NSInteger packetIndex;
@property(nonatomic,assign) NSInteger packetAmount;
@property(nonatomic,strong) EGMReadMassDataCmd *massCmd;
@property(nonatomic,copy) SDKDataChangedBlock dataChangeBlock;

+(EGMOnMassDataListener*) getNotifyingMassDataListener;
+(void) setNotifyingMassDataListener:(EGMOnMassDataListener*) listener;
-(void) allPacketsReceived:(NSDictionary*)allPacketsMapMap;
-(void) receivedOnePacket:(NSData*)data;

-(BOOL) validateData:(NSData*)data;
-(NSInteger)getPacketIndex:(NSData*)data;
-(NSInteger)getPacketAmount:(NSData*)data;
-(NSData*)getWorkData:(NSData*)data;
-(BOOL)isTransferFinished:(NSData*)data;
-(void) cleanUp;
-(BOOL)shouldSetAccurateTimeout;
@end
